package com.kuaiditu.assistant.api.assistant_api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.AppUtils;
import com.kuaiditu.assistant.api.ApiManager;
import com.kuaiditu.assistant.api.assistant_api.base.AssistantRequest;
import com.kuaiditu.assistant.api.assistant_api.base.AssistantResponse;
import com.kuaiditu.assistant.api.assistant_api.respone.LoginRes;
import com.kuaiditu.assistant.api.assistant_api.respone.TaskSquareRes;
import com.kuaiditu.assistant.common.Constants;
import com.kuaiditu.assistant.db.ExpressEntity;
import com.kuaiditu.assistant.entity.AssistantUser;
import com.kuaiditu.assistant.entity.Balance;
import com.kuaiditu.assistant.entity.Operator;
import com.kuaiditu.assistant.entity.TaskExpressItem;
import com.kuaiditu.assistant.entity.TaskSquareEn;
import com.kuaiditu.assistant.module.retrofit.impl.AssistantConverterAdapter;
import com.kuaiditu.assistant.module.retrofit.FastJsonConverterFactory;
import com.kuaiditu.assistant.module.storage.AssistantUserStorage;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * Created by Eenie on 2017/8/31.
 * Email: eeniework@gmail.com
 * Des:
 */

public class AssistantApi {
    public static final int ACTION_LOGIN = 0;
    public static final int ACTION_REGISTER = 1;
    public static final String TYPE_TASK_END = "end";
    public static final String TYPE_TASK_NOT_END = "notEnd";
    private int DEFAULT_PAGE_SIZE = 20;
    private AssistantService mAssistantService;
    private static final String host = Constants.BASE_URL;
    private AssistantUserStorage mAssistantUserStorage;
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    private ApiManager mApiManager;

    public AssistantApi(OkHttpClient client, AssistantUserStorage assistantUserStorage, ApiManager apiManager) {
        mAssistantUserStorage = assistantUserStorage;
        mApiManager = apiManager;
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(host)
                .client(client)
                .addConverterFactory(FastJsonConverterFactory.create(new AssistantConverterAdapter(mAssistantUserStorage, this)))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        mAssistantService = retrofit.create(AssistantService.class);
    }


    public ObservableSource<TaskSquareRes> fetchTask(int page) {
        Map<String, Object> param = new HashMap<>();
        param.put("page", page);
        param.put("pageNum", DEFAULT_PAGE_SIZE);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierOrder.listOrder", param)
                .UserFlag(true, false))
                .flatMap(new Function<AssistantResponse, ObservableSource<TaskSquareRes>>() {
                    @Override
                    public ObservableSource<TaskSquareRes> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        TaskSquareRes res = (TaskSquareRes) assistantResponse.getRespData(TaskSquareRes.class);
                        return Observable.just(res);
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<JSONObject> fetchTaskDes(int task_id) {
        Map<String, Object> param = new HashMap<>();
        param.put("order_id", task_id);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierOrder.orderNote", param)
                .UserFlag(true, true))
                .flatMap(new Function<AssistantResponse, ObservableSource<JSONObject>>() {
                    @Override
                    public ObservableSource<JSONObject> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        JSONObject res = assistantResponse.getRespDataEn();
                        return Observable.just(res);
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    public ObservableSource<AssistantUser> login(String mobile, String random) {
        Map<String, Object> param = new HashMap<>();
        param.put("mobile", mobile);
        param.put("random", random);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierLogin.login", param))
                .flatMap(new Function<AssistantResponse, ObservableSource<AssistantUser>>() {
                    @Override
                    public ObservableSource<AssistantUser> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        LoginRes res = (LoginRes) assistantResponse.getRespData(LoginRes.class);
                        AssistantUser assistantUser = res.getCourier();
                        return Observable.just(assistantUser);
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<AssistantUser>() {
                    @Override
                    public void accept(AssistantUser assistantUser) throws Exception {
                        mAssistantUserStorage.saveUser(assistantUser);
                    }
                });
    }

    public ObservableSource<JSONObject> register(String mobile, String random) {
        Map<String, Object> param = new HashMap<>();
        param.put("mobile", mobile);
        param.put("random", random);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierLogin.reg", param))
                .flatMap(new Function<AssistantResponse, ObservableSource<JSONObject>>() {
                    @Override
                    public ObservableSource<JSONObject> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        String res = (String) assistantResponse.getRespData(String.class);
                        return Observable.just(JSON.parseObject(res));
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    public ObservableSource<AssistantResponse> sendSmsCode(String mobile, int action) {
        String method;
        if (action == ACTION_LOGIN) {
            method = "courierLogin.getLoginRandom";
        } else {
            method = "courierLogin.getRegRandom";
        }
        Map<String, Object> param = new HashMap<>();
        param.put("mobile", mobile);
        return mAssistantService.reqData(AssistantRequest.DEFAULT(method, param))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<AssistantResponse> takeTask(String order_id) {
        Map<String, Object> param = new HashMap<>();
        param.put("order_id", order_id);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierOrder.pickOrder", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public Observable<AssistantResponse> addOrder(ExpressEntity expressEntity, Operator operator) {
        Map<String, Object> param = new HashMap<>();
        param.put("order_id", expressEntity.getTask_id());
        param.put("expressOrderNo", expressEntity.getExpress_num());
        param.put("realName", operator.getName());
        param.put("status", expressEntity.getState_code() == ExpressEntity.EXPRESS_STATE_CODE_SEND_TPOS_SUCCESS ? "ADD" : "NOTADD");
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.addOrder", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"));
    }

    public Observable<AssistantResponse> signOrder(ExpressEntity expressEntity, Operator operator) {
//      {    	"realName":"黄飞",    	"courier_id":1,    	"order_id":1,    	"expressOrderNo":"123123123123"    }
        Map<String, Object> param = new HashMap<>();
        param.put("order_id", expressEntity.getTask_id());
        param.put("expressOrderNo", expressEntity.getExpress_num());
        param.put("realName", operator.getName());
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.signOrder", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<AssistantResponse> completeAddOrder(String order_id) {
//{    	"courier_id":1,    	"order_id":1    }
        Map<String, Object> param = new HashMap<>();
        param.put("order_id", order_id);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.endAddOrder", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<AssistantResponse> completeSignOrder(String order_id) {
        Map<String, Object> param = new HashMap<>();
        param.put("order_id", order_id);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.endSignOrder", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<TaskSquareRes> fetchPersonTask(int page, String type) {
        Map<String, Object> param = new HashMap<>();
        param.put("page", page);
        param.put("pageNum", DEFAULT_PAGE_SIZE);
        param.put("type", type);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.myOrder", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .flatMap(new Function<AssistantResponse, ObservableSource<TaskSquareRes>>() {
                    @Override
                    public ObservableSource<TaskSquareRes> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        TaskSquareRes res = (TaskSquareRes) assistantResponse.getRespData(TaskSquareRes.class);
                        return Observable.just(res);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<List<TaskExpressItem>> fetchTaskOrderList(int task_id) {
        Map<String, Object> param = new HashMap<>();
        param.put("order_id", task_id);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.orderDetail", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .flatMap(new Function<AssistantResponse, ObservableSource<List<TaskExpressItem>>>() {
                    @Override
                    public ObservableSource<List<TaskExpressItem>> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        TaskSquareEn taskSquareEn = assistantResponse.getRespDataEn().getJSONObject("order").toJavaObject(TaskSquareEn.class);
                        List<TaskExpressItem> taskExpressItems = taskSquareEn.getListOrderItem();
                        return Observable.just(taskExpressItems);
                    }

                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<Balance> fetchBalance(int page) {
        Map<String, Object> param = new HashMap<>();
        param.put("page", page);
        param.put("pageNum", DEFAULT_PAGE_SIZE);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.courierProcess", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .flatMap(new Function<AssistantResponse, ObservableSource<Balance>>() {
                    @Override
                    public ObservableSource<Balance> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        Balance taskSquareEn = (Balance) assistantResponse.getRespData(Balance.class);
                        return Observable.just(taskSquareEn);
                    }

                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    public ObservableSource<AssistantResponse> saveAliCode(String aliCode, String aliName) {

//      {        "courier_id": "1",        "courier_aliCode":"12314123123",        "courier_aliCodeName":"黄飞"    }

        Map<String, Object> param = new HashMap<>();
        param.put("courier_aliCode", aliCode);
        param.put("courier_aliCodeName", aliName);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierLogin.updateCourierInfo", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<AssistantResponse> deposit(String money) {
        Map<String, Object> param = new HashMap<>();
        param.put("money", money);
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierCenter.turnoutMoney", param)
                .UserFlag(true, true)
                .setTokenKeyName("courier_id"))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

    public ObservableSource<AssistantResponse> checkVersion() {
        Map<String, Object> param = new HashMap<>();
        param.put("source", "ANDROID");
        param.put("versionCode", AppUtils.getAppVersionCode());
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierLogin.getVersionInfo", param))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }


    public ObservableSource<AssistantUser> refreshUser() {
        Map<String, Object> param = new HashMap<>();
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierLogin.courierInfo", param)
                .UserFlag(true, false)
                .setTokenKeyName("courier_id"))
                .flatMap(new Function<AssistantResponse, ObservableSource<AssistantUser>>() {
                    @Override
                    public ObservableSource<AssistantUser> apply(@NonNull AssistantResponse assistantResponse) throws Exception {
                        LoginRes res = (LoginRes) assistantResponse.getRespData(LoginRes.class);
                        AssistantUser assistantUser = res.getCourier();
                        return Observable.just(assistantUser);
                    }
                }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnNext(new Consumer<AssistantUser>() {
                    @Override
                    public void accept(AssistantUser assistantUser) throws Exception {
                        mAssistantUserStorage.saveUser(assistantUser);
                    }
                });
    }



    public ObservableSource<AssistantResponse> auth(String idcardFront,String imgIdcardReverse) {
        Map<String, Object> param = new HashMap<>();
        param.put("courier_realname", mAssistantUserStorage.getUser().getCourier_mobile());
        param.put("courier_IdCardPicture", idcardFront);
        param.put("courier_IdCardHandPicture", imgIdcardReverse);
        param.put("courier_id", mAssistantUserStorage.getUser().getCourier_id());
        return mAssistantService.reqData(AssistantRequest.DEFAULT("courierLogin.authCourier", param))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }

}
